;; This example shows the correct method to read the keyboard and
;; joysticks on the CPC, CPC+ and KC Compact.
;;
;; This source is compatible with the CPC+.
;;
;; The following is assumed before executing of this algorithm:
;; - I/O port A of the PSG is set to input,
;; - PPI Port A is set to output
.read_matrix
ld hl,matrix_buffer ; buffer to store matrix data
ld bc,&f40e ; write PSG register index (14) to PPI port A (databus to PSG)
out (c),c
ld b,&f6
in a,(c)
and &30
ld c,a
or &C0 ; bit 7=bit 6=1 (PSG operation: write register index)
out (c),a ; set PSG operation -> select PSG register 14
;; at this point PSG will have register 14 selected.
;; any read/write operation to the PSG will act on this register.
out (c),c ; bit 7=bit 6=0 (PSG operation: inactive)
inc b
ld a,&92
out (c),a ; write PPI control: port A: input, port B: input, port C upper: output
; port C lower: output
push bc
set 6,c ; bit 7=0, bit 6=1 (PSG operation: read register data)
.scan_key
ld b,&f6
out (c),c ;set matrix line & set PSG operation
ld b,&f4 ;PPI port A (databus to/from PSG)
in a,(c) ;get matrix line data from PSG register 14
cpl ;invert data: 1->0, 0->1
;if a key/joystick button is pressed bit will be "1"
;keys that are not pressed will be "0"
ld (hl),a ;write line data to buffer
inc hl ;update position in buffer
inc c ;update line
ld a,c
and &0f
cp &0a ;scanned all rows?
jr nz,scan_key ;no loop and get next row
;; scanned all rows
pop bc
ld a,&82 ;write PPI Control: Port A: Output, Port B: Input, Port C upper: output, Port C lower: output.
out (c),a
dec b
out (c),c ;set PSG operation: bit7=0, bit 6=0 (PSG operation: inactive)
ret
.matrix_buffer
defs 16